package com.emm.yixun.website.listeners;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.IdentityService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.apache.commons.lang3.StringUtils;
import com.emm.yixun.common.enums.ProcessTypeEnums;
import com.emm.yixun.common.enums.ResponseEnums;
import com.emm.yixun.common.model.ActcommitLog;
import com.emm.yixun.common.model.BusinessAbnorma;
import com.emm.yixun.common.model.PayDeposit;
import com.emm.yixun.common.model.Subscribe;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.ActcommitLogDto;
import com.emm.yixun.common.model.dto.BusinessAbnormaDto;
import com.emm.yixun.common.model.dto.NoticeEntity;
import com.emm.yixun.common.model.dto.PayDepositDto;
import com.emm.yixun.common.model.dto.ProjectRoomDto;
import com.emm.yixun.common.model.dto.SubscribeDto;
import com.emm.yixun.common.model.enums.AuditStatusEnum;
import com.emm.yixun.common.model.enums.BusinessAbnormaEnum;
import com.emm.yixun.common.model.enums.BusinessTypeEnum;
import com.emm.yixun.common.model.enums.RoomStatusEnum;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.customer.service.PayDepositServiceFacade;
import com.emm.yixun.customer.service.SubscribeServiceFacade;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.marketing.service.BusinessAbnormaServiceFacade;
import com.emm.yixun.system.service.UserServiceFacade;
import com.emm.yixun.system.service.notice.subscribe.SubscribeDiscountNoticeFacade;
import com.emm.yixun.website.common.utils.SpringWebContextUtil;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.system.log.ActCommitLogService;

public class SubscribeDiscountListeners implements Serializable,
		ExecutionListener {
	private static final long serialVersionUID = -6543142814628305903L;

	@Override
	public void notify(DelegateExecution execution) throws Exception {
		String id = execution.getProcessBusinessKey();
		String processInstanceId = execution.getProcessInstanceId();
		SubscribeServiceFacade subscribeServiceFacade = getSubscribeServiceFacade();
		Response<Subscribe> subscribeResponse = subscribeServiceFacade
				.findById(Long.valueOf(id));
		if (!subscribeResponse.isSuccess()) {
			throw new Exception("认购记录不存在");
		}
		Subscribe subscribe = subscribeResponse.getEntity();
		if (null == subscribe) {
			throw new Exception("认购记录不存在");
		}
		
		
		Long projectId = subscribe.getProjectId();
		BusinessAbnormaServiceFacade businessAbnormaServiceFacade = getBusinessAbnormaServiceFacade();
		ActivitiProcessServiceImpl activitiProcessService = getActivitiProcessServiceImpl();
		if (activitiProcessService.isCheckPass(processInstanceId)) {
			/**
			 * 1.修改认购折扣审核状态为通过 2.发起认筹审批
			 */
			String startProcessKey = activitiProcessService.getProcessKey(
					subscribe.getMerchantId(), projectId,
					ProcessTypeEnums.PROCESS_KEY_5);
			if (StringUtils.isEmpty(startProcessKey)) {
				throw new Exception("项目未设置认购审批流程,请去项目流程菜单配置！");
			}
			BusinessAbnormaDto queryDto = new BusinessAbnormaDto();
			queryDto.setBusinessId(subscribe.getId());
			queryDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_0.getNo());
			queryDto.setProcInstId(processInstanceId);
			ResponseList<BusinessAbnorma> responseList = businessAbnormaServiceFacade.findByDto(queryDto);
			if (null != responseList && null != responseList.getEntity()&& responseList.getEntity().size() > 0) {
				BusinessAbnorma businessAbnorma = responseList.getEntity().get(0);
				
				boolean flag = checkAuditCommit(businessAbnorma);
				if(!flag) {
					throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
				}
				
				BusinessAbnormaDto updateBADto = new BusinessAbnormaDto();
				updateBADto.setId(businessAbnorma.getId());
				updateBADto.setCheckDate(new Date());
				updateBADto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				businessAbnormaServiceFacade.updateByPrimaryKey(updateBADto,true);
			}
			User user = getUserServiceFacade().findById(subscribe.getCreateUserId()).getEntity();
			Map<String, Object> variables = new HashMap<String, Object>();
			getIdentityService().setAuthenticatedUserId(user.getUserAccount());
            //启动认购流程
			String pid = activitiProcessService.startProcessInstance(user.getMerchantId(), projectId,
					startProcessKey, subscribe.getId().toString(), variables);
			/*
			 * ProcessInstance processInstance =
			 * getRuntimeService().startProcessInstanceByKey
			 * ("cusSubscribe",subscribe.getId().toString(),variables);
			 */
			SubscribeDto updateSubscribeDto = new SubscribeDto();
			updateSubscribeDto.setId(subscribe.getId());
			updateSubscribeDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
			updateSubscribeDto.setProcInstId(pid);
			subscribeServiceFacade.updateByPrimaryKey(updateSubscribeDto, true);
			/**
			 * （认购折扣审核通过）推送消息到app
			 * 
			 * @author ny
			 * @param param
			 *            noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(subscribe.getId());
			noticeEntity.setNoticeType("5");
			noticeEntity.setProcessInstanceId(processInstanceId);
			noticeEntity.setAudStatus("3");
			getSubscribeDiscountNoticeFacade().createSubscribeDiscountNotice(noticeEntity);
		} else {
			/**
			 * 1.修改认购折扣审核状态为不通过 2.修改房源状态为未售或者认筹
			 */

			BusinessAbnormaDto queryDto = new BusinessAbnormaDto();
			queryDto.setBusinessId(subscribe.getId());
			queryDto.setBusinessType(BusinessTypeEnum.SUBSCRIBE.getNo());
			queryDto.setProcInstId(processInstanceId);
			queryDto.setOrders(" t.id desc ");
			ResponseList<BusinessAbnorma> responseList = businessAbnormaServiceFacade
					.findByDto(queryDto);
			if (null != responseList && null != responseList.getEntity()
					&& responseList.getEntity().size() > 0) {
				BusinessAbnorma businessAbnorma = responseList.getEntity().get(0);
				
				boolean flag = checkAuditCommit(businessAbnorma);
				if(!flag) {
					throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
				}
				
				BusinessAbnormaDto updateBADto = new BusinessAbnormaDto();
				updateBADto.setId(businessAbnorma.getId());
				updateBADto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
				updateBADto.setCheckDate(new Date());
				businessAbnormaServiceFacade.updateByPrimaryKey(updateBADto,
						true);
			}

			// 房源状态为未售或者认筹
			ProjectRoomDto projectRoomDto = new ProjectRoomDto();
			projectRoomDto.setId(subscribe.getRoomId());

			PayDepositDto payDepositDto = new PayDepositDto();
			payDepositDto.setM_auditStatus(" and t.audit_status in (1,3)");
			payDepositDto.setRoomId(subscribe.getRoomId());
			ResponseList<PayDeposit> payDepositList = getPayDepositServiceFacade()
					.findByDtoJ(payDepositDto);
			if (payDepositList.getEntity() == null
					|| payDepositList.getEntity().size() == 0) {
				projectRoomDto
						.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());
			} else {
				projectRoomDto.setRoomStatus(RoomStatusEnum.RESERVE.getNo());
			}
			getProjectRoomServiceFacade().updateByPrimaryKey(projectRoomDto,
					true);

			// 认购审核状态改为‘退回’
			SubscribeDto updateSubscribeDto = new SubscribeDto();
			updateSubscribeDto.setId(subscribe.getId());
			updateSubscribeDto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
			updateSubscribeDto.setCheckDate(new Date());
			subscribeServiceFacade.updateByPrimaryKey(updateSubscribeDto, true);

			/**
			 * （认购折扣审核不通过）推送消息到app
			 * 
			 * @author ny
			 * @param param
			 *            noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(subscribe.getId());
			noticeEntity.setNoticeType("5");
			noticeEntity.setProcessInstanceId(processInstanceId);
			noticeEntity.setAudStatus("2");
			getSubscribeDiscountNoticeFacade().createSubscribeDiscountNotice(noticeEntity);
		}
	}
	
	/**
	 * 前置判断,审核记录是否已经提交,防止重复提交
	 * 产生原因: 提交审核,后台处理中时,刷新页面再次提交审核,会重复
	 * true: 可继续执行
	 * false: 不可执行
	 */
	public boolean checkAuditCommit(BusinessAbnorma entity) {
		// 业务数据为null时,默认通过.为了不改变老业务,不影响流程正常行走
		if (null == entity) {
			return true;
		}
		return getActcommitLogService().checkActCommit(entity.getAuditStatus(), entity.getMerchantId(), entity.getId(),
				entity.getProcInstId(), "认购折扣", "PC");
	}
	
	private ActCommitLogService getActcommitLogService(){
		return (ActCommitLogService)SpringWebContextUtil.getApplicationContext().getBean("actCommitLogService");
	}

	private PayDepositServiceFacade getPayDepositServiceFacade() {
		return (PayDepositServiceFacade) SpringWebContextUtil.getApplicationContext().getBean("payDepositServiceFacade");
	}

	private SubscribeDiscountNoticeFacade getSubscribeDiscountNoticeFacade() {
		return (SubscribeDiscountNoticeFacade) SpringWebContextUtil.getApplicationContext().getBean("subscribeDiscountNoticeFacade");
	}

	private BusinessAbnormaServiceFacade getBusinessAbnormaServiceFacade() {
		return (BusinessAbnormaServiceFacade) SpringWebContextUtil.getApplicationContext().getBean("businessAbnormaServiceFacade");
	}

	private ProjectRoomServiceFacade getProjectRoomServiceFacade() {
		return (ProjectRoomServiceFacade) SpringWebContextUtil.getApplicationContext().getBean("projectRoomServiceFacade");
	}

	private SubscribeServiceFacade getSubscribeServiceFacade() {
		return (SubscribeServiceFacade) SpringWebContextUtil.getApplicationContext().getBean("subscribeServiceFacade");
	}

	private ActivitiProcessServiceImpl getActivitiProcessServiceImpl() {
		return (ActivitiProcessServiceImpl) SpringWebContextUtil.getApplicationContext().getBean("activitiProcessServiceImpl");
	}

	private IdentityService getIdentityService() {
		return (IdentityService) SpringWebContextUtil.getApplicationContext().getBean("identityService");
	}
	private UserServiceFacade getUserServiceFacade() {
		return (UserServiceFacade) SpringWebContextUtil.getApplicationContext().getBean("userServiceFacade");
	}

}
